package com.cxx.purchasecharge.component.controller.auditlog;

import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cxx.purchasecharge.component.bean.ActionResult;
import com.cxx.purchasecharge.component.bean.ActionResult.ActionResultStatus;
import com.cxx.purchasecharge.component.bean.DataGridRequestForm;
import com.cxx.purchasecharge.component.bean.GenericPagingResult;
import com.cxx.purchasecharge.component.bean.LogSearchRequestForm;
import com.cxx.purchasecharge.component.bean.auditlog.LogBean;
import com.cxx.purchasecharge.component.bean.auditlog.LogContentBean;
import com.cxx.purchasecharge.component.utils.AjaxUtils;
import com.cxx.purchasecharge.component.utils.BeanConvertUtils;
import com.cxx.purchasecharge.component.utils.ComponentConstants;
import com.cxx.purchasecharge.component.utils.MessageProperties;
import com.cxx.purchasecharge.core.model.persistence.auditlog.Log;
import com.cxx.purchasecharge.core.model.persistence.auditlog.LogContent;
import com.cxx.purchasecharge.dal.auditlog.LogContentDao;
import com.cxx.purchasecharge.dal.auditlog.LogDao;

@Controller
@RequestMapping ("/log")
public class LogController
{
    private static final Logger LOGGER = Logger.getLogger (LogController.class);

    @Autowired
    private LogDao logDao;
    @Autowired
    private LogContentDao logContentDao;

    @RequestMapping (value = "/")
    public String redirectToLogManagement (ModelMap model)
    {
        return "logManagement";
    }

    @RequestMapping (value = "/getLogs", method = RequestMethod.POST)
    public @ResponseBody
    String getLogs (DataGridRequestForm dataGridRequestForm, LogSearchRequestForm searchRequestForm)
    {
        LOGGER.debug (dataGridRequestForm);
        int page = dataGridRequestForm.getPage () - 1;
        int size = dataGridRequestForm.getRows ();
        String sortField = parseSortField (dataGridRequestForm.getSort ());
        String order = dataGridRequestForm.getOrder ();
        Pageable pageable = new PageRequest (page, size, new Sort ("asc".equalsIgnoreCase (order) ? Direction.ASC
                                                                                                 : Direction.DESC,
                                                                   sortField));
        Page <Log> logPage = logDao.findBySearchForm (pageable,
                                                      BeanConvertUtils.logSearchRequestForm2LogSearchForm (searchRequestForm));

        List <LogBean> logBeans = new ArrayList <LogBean> ();
        List <Log> orderList = logPage.getContent ();
        if (!CollectionUtils.isEmpty (orderList))
        {
            for (Log log : orderList)
            {
                logBeans.add (BeanConvertUtils.log2LogBean (log));
            }
        }
        long total = logPage.getTotalElements ();
        GenericPagingResult <LogBean> logPagingResult = new GenericPagingResult <LogBean> ();
        logPagingResult.setRows (logBeans);
        logPagingResult.setTotal (total);

        JSONObject jsonObject = JSONObject.fromObject (logPagingResult);
        return jsonObject.toString ();
    }
    
    private String parseSortField (final String sortField)
    {
        String sortFieldAfterParse = "date";
        if (!StringUtils.isBlank (sortField))
        {
            if (ComponentConstants.LOG_DATE_TIME.equalsIgnoreCase (sortField))
            {
                sortFieldAfterParse = "date";
            }
        }
        return sortFieldAfterParse;
    }

    @RequestMapping (value = "/getLogContents", method = RequestMethod.POST)
    public @ResponseBody
    String getLogContents (@RequestParam String logId)
    {
        LOGGER.debug ("getLogContents by logId: " + logId);
        List <LogContentBean> logContentBeans = new ArrayList <LogContentBean> ();
        if (StringUtils.isNotBlank (logId))
        {
            List <LogContent> logContents = logContentDao.findByLog (Long.parseLong (logId));
            if (!CollectionUtils.isEmpty (logContents))
            {
                for (LogContent lc : logContents)
                {
                    logContentBeans.add (BeanConvertUtils.logContent2LogContentBean (lc));
                }
            }
        }
        JSONArray json = JSONArray.fromObject (logContentBeans);
        return json.toString ();
    }

    @RequestMapping (value = "/delLog", method = RequestMethod.POST)
    public @ResponseBody
    String deleteLog (@RequestParam String ids)
    {
        if (StringUtils.isNotBlank (ids))
        {
            List <Log> logs = new ArrayList <Log> ();
            Log log;
            if (ids.indexOf (";") != -1)
            {
                String[] idArr = ids.split (";");
                for (String typeId : idArr)
                {
                    log = new Log ();
                    log.setId (Long.parseLong (typeId));
                    logs.add (log);
                }
            }
            else
            {
                log = new Log ();
                log.setId (Long.parseLong (ids));
                logs.add (log);
            }

            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                logDao.delete (logs);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_SUCCESS,
                                                                                       ComponentConstants.MSG_LOG))
                                 .build ();
            }
            catch (Exception e)
            {
                LOGGER.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_FAIL,
                                                                                       ComponentConstants.MSG_LOG))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            LOGGER.error (ActionResultStatus.BAD_REQUEST);
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
    }
}
